package com.elitedatai.mchtest.map.service.impl;

import com.dji.sdk.cloudapi.flightarea.GeofenceTypeEnum;
import com.dji.sdk.cloudapi.flightarea.GeometrySubTypeEnum;
import com.elitedatai.mchtest.common.util.CustomBeanUtil;
import com.elitedatai.mchtest.map.model.dto.FlightAreaPropertyDTO;
import com.elitedatai.mchtest.map.model.dto.FlightAreaPropertyUpdate;
import com.elitedatai.mchtest.map.model.entity.FlightAreaPropertyEntity;
import com.elitedatai.mchtest.map.repository.FlightAreaPropertyRepository;
import com.elitedatai.mchtest.map.service.IFlightAreaPropertyServices;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;


@Service
@Transactional
public class FlightAreaPropertyServiceImpl implements IFlightAreaPropertyServices {

    @Autowired
    private FlightAreaPropertyRepository repository;

    @Override
    public List<FlightAreaPropertyDTO> getPropertyByElementIds(List<String> elementIds) {
        if (CollectionUtils.isEmpty(elementIds)) {
            return Collections.emptyList();
        }
        List<FlightAreaPropertyEntity> flightAreaPropertyEntities = repository.findByElementIds(elementIds);
        return flightAreaPropertyEntities.stream().map(this::fillProperty).collect(Collectors.toList());
    }

    @Override
    public Long saveProperty(FlightAreaPropertyDTO property) {
        FlightAreaPropertyEntity entity = dto2Entity(property);
        long id = repository.save(entity).getId();
        return id > 0 ? entity.getId():id;
    }

    @Override
    public Long deleteProperty(String elementId) {
        FlightAreaPropertyEntity byElementId = repository.findByElementId(elementId);
        if(Objects.isNull(byElementId)){
            return 0L;
        }
        repository.deleteByElementId(elementId);
        return byElementId.getId();
    }

    @Override
    public Long updateProperty(FlightAreaPropertyUpdate property) {
        FlightAreaPropertyEntity byElementId = repository.findByElementId(property.getElementId());
        if (Objects.isNull(byElementId)) {
            return 0L;
        }
        FlightAreaPropertyEntity updateEntity = update2Entity(property);
        FlightAreaPropertyEntity copyed = CustomBeanUtil.copyProperties(updateEntity, byElementId);
        repository.save(copyed);
        return copyed.getId();
    }

    private FlightAreaPropertyDTO fillProperty(FlightAreaPropertyEntity entity) {
        if (Objects.isNull(entity)) {
            return null;
        }
        FlightAreaPropertyDTO.FlightAreaPropertyDTOBuilder builder = FlightAreaPropertyDTO.builder()
                .elementId(entity.getElementId())
                .status(entity.getEnable())
                .type(GeofenceTypeEnum.find(entity.getType()))
                .subType(Optional.ofNullable(entity.getSubType()).map(GeometrySubTypeEnum::find).orElse(null))
                .radius(entity.getRadius().floatValue() / 100);

        return builder.build();
    }

    private FlightAreaPropertyEntity dto2Entity(FlightAreaPropertyDTO dto) {
        if (Objects.isNull(dto)) {
            return null;
        }
        return FlightAreaPropertyEntity.builder()
                .elementId(dto.getElementId())
                .enable(dto.getStatus())
                .subType(Optional.ofNullable(dto.getSubType()).map(GeometrySubTypeEnum::getSubType).orElse(null))
                .type(dto.getType().getType())
                .radius(Optional.ofNullable(dto.getRadius()).map(radius -> radius * 100).map(Float::intValue).orElse(null))
                .build();
    }

    private FlightAreaPropertyEntity update2Entity(FlightAreaPropertyUpdate property) {
        if (Objects.isNull(property)) {
            return null;
        }
        return FlightAreaPropertyEntity.builder()
                .radius(Optional.ofNullable(property.getRadius()).map(radius -> radius * 100).map(Float::intValue).orElse(null))
                .enable(property.getStatus())
                .elementId(property.getElementId())
                .build();
    }
}
